/*****************************************************************************
Copyright 2006 Kervin L. Pierre
    EMAIL: otlkcon@adevsoft.com

This file is part of Otlkcon.

Otlkcon is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.

Otlkcon is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Lesser GNU General Public License for more details.

You should have received a copy of the Lesser GNU General Public License
along with Otlkcon; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

*******************************************************************************/

#pragma once
#include "StdAfx.h"
#include "O_IProp.h"
#include "O_IFolder.h"
#include <otlkcon_calendar_component.h>

#include <string>
#include <map>

using namespace std;

class O_IMSProvider;

class otlkcon_generic_msgstore : public O_IProp
{
public:
	//MAPI_IUNKNOWN_METHODS(IMPL);
    MAPI_IMSGSTORE_METHODS(IMPL);

	//Override this method to add additional functionality
	STDMETHODIMP_(ULONG) AddRef(void);
	STDMETHODIMP_(ULONG) Release(void);

	// RESOLVED_BUG: 
    //     COM is finicky about vtable order.  Use the above
    //     macros garantee correct order.

    	/*STDMETHODIMP Advise(ULONG cbEntryID,					\
				LPENTRYID					lpEntryID,					\
				ULONG						ulEventMask,				\
				LPMAPIADVISESINK			lpAdviseSink,				\
				ULONG *lpulConnection);
	STDMETHODIMP Unadvise(ULONG ulConnection);
	STDMETHODIMP CompareEntryIDs(ULONG cbEntryID1,					\
				LPENTRYID					lpEntryID1,					\
				ULONG						cbEntryID2,					\
				LPENTRYID					lpEntryID2,					\
				ULONG						ulFlags,					\
				ULONG *lpulResult);
	STDMETHODIMP OpenEntry(ULONG						cbEntryID,					\
				LPENTRYID					lpEntryID,					\
				LPCIID						lpInterface,				\
				ULONG						ulFlags,					\
				ULONG *					lpulObjType,				\
				LPUNKNOWN *				lppUnk);
	STDMETHODIMP SetReceiveFolder(LPTSTR						lpszMessageClass,			\
				ULONG						ulFlags,					\
				ULONG						cbEntryID,					\
				LPENTRYID					lpEntryID);
	STDMETHODIMP GetReceiveFolder(LPTSTR						lpszMessageClass,			\
				ULONG						ulFlags,					\
				ULONG *					lpcbEntryID,				\
				LPENTRYID *				lppEntryID,					\
				LPTSTR *				lppszExplicitClass);
	STDMETHODIMP GetReceiveFolderTable(ULONG						ulFlags,					\
				LPMAPITABLE *			lppTable);
	STDMETHODIMP StoreLogoff(ULONG *lpulFlags);
	STDMETHODIMP AbortSubmit(ULONG						cbEntryID,					\
				LPENTRYID					lpEntryID,					\
				ULONG						ulFlags);
	STDMETHODIMP GetOutgoingQueue(ULONG						ulFlags,					\
				LPMAPITABLE *			lppTable);\
	STDMETHODIMP SetLockState(LPMESSAGE					lpMessage,					\
				ULONG						ulLockState);
	STDMETHODIMP FinishedMsg(ULONG						ulFlags,					\
				ULONG						cbEntryID,					\
				LPENTRYID					lpEntryID);
	STDMETHODIMP NotifyNewMail(LPNOTIFICATION				lpNotification);*/

    otlkcon_generic_msgstore(void);
    ~otlkcon_generic_msgstore(void);

    HRESULT Destroy();
    HRESULT Create(char * df, MAPIUID ig, otlkcon_memory *m );

    HRESULT Create(char * df, MAPIUID ig, MAPIUID tg, otlkcon_memory *m );
	
	STDMETHODIMP InternalAdvise(
		ULONG cbEntryID,
		LPENTRYID					lpEntryID,
		ULONG						ulEventMask,
		LPMAPIADVISESINK			lpAdviseSink,
		ULONG						ulFlags, // provider internaly uses NOTIFY_SYNC
		ULONG						*lpulConnection);

	//! For use from O_ServiceEntry while configuring MsgStore
	static HRESULT CreateStoreEntryID(O_ENTRYID** lppNewEntry, otlkcon_memory *mem );

    HRESULT Load(char *df, O_ENTRYID *eid, otlkcon_memory *m );
    HRESULT Notify( O_ENTRYID *key, ULONG cNotification,  LPNOTIFICATION lpNotifications,
                ULONG *lpulFlags );

    HRESULT ProcessEvent( otlkcon_event_struct *ev );
    HRESULT OnReloadConfig( otlkcon_event_struct *ev );

    ULONG GetObjCount(void);

    HRESULT RemoveObject( O_ENTRYID *eid, O_ENTRYID *parEid );
    
    HRESULT ValidateEntryID( O_ENTRYID *eid, ULONG cbEntryID, ULONG flags, ULONG interfaces );

    otlkcon_memory *memObj;

    int objCount;

	//Keep the MAPI Support Object near
	LPMAPISUP lpMAPISup;

    // Map of top level folders
    map<string, O_IFolder *> topLevelFolders;

    //Advise arrays
    vector<LPENTRYID>           adviseEntryIDs;
    vector<ULONG>               adviseCbEntryIDs;
    vector<LPMAPIADVISESINK>    adviseSinks;
    vector<ULONG>               adviseMasks;

    // Map of loaded objects
    map< O_ENTRYID *, void *, otlkcon_entryid_less > loadedObjects;

    // Spooler context?
    BOOL isSpoolerStore;

    ULONG ulUIParam;
    ULONG logonFlags;
    otlkcon_prop2str *prop2str;
	
	O_IMSProvider* m_lpParentProvider;
	ULONG		   m_ulCachedStoreLogOffFlags;    

    // FIXME: The following map needs a SQL counterpart.
    //! Map of account ID to appointment folder EntryIDs in this store.
    map<wstring,O_IFolder*> foreignAppointmentFolders;
};


